package agriculture.util;
//这个工具类实现了雪花算法的核心逻辑，用于生成唯一的 ID。
public class SnowflakeIdWorker {
    // 定义各部分位数
    private static final long WORKER_ID_BITS = 10L; // 机器ID占的位数
    private static final long SEQUENCE_BITS = 12L; // 序列号占的位数
    private static final long WORKER_ID_SHIFT = SEQUENCE_BITS; // 机器ID偏移量
    private static final long TIMESTAMP_SHIFT = WORKER_ID_SHIFT + WORKER_ID_BITS; // 时间戳偏移量
    private static final long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS); // 序列号的掩码

    private final long workerId; // 机器ID
    private long sequence = 0L; // 序列号
    private long lastTimestamp = -1L; // 上次生成ID的时间戳

    public SnowflakeIdWorker(long workerId) {
        if (workerId > 1023 || workerId < 0) {
            throw new IllegalArgumentException("Worker ID must be between 0 and 1023");
        }
        this.workerId = workerId;
    }

    // 生成ID
    public synchronized long generateId() {
        long timestamp = System.currentTimeMillis();
        if (timestamp < lastTimestamp) {
            throw new RuntimeException("Clock moved backwards. Refusing to generate ID");
        }

        if (timestamp == lastTimestamp) {
            // 如果当前时间和上次生成ID的时间相同，则自增序列号
            sequence = (sequence + 1) & SEQUENCE_MASK;
            if (sequence == 0) {
                // 如果序列号已经达到最大值，则等到下一毫秒
                timestamp = waitForNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0; // 重置序列号
        }

        lastTimestamp = timestamp;

        // 按照雪花算法的规则，构造64位ID
        return ((timestamp - 1288834974657L) << TIMESTAMP_SHIFT) | (workerId << WORKER_ID_SHIFT) | sequence;
    }

    private long waitForNextMillis(long lastTimestamp) {
        long timestamp = System.currentTimeMillis();
        while (timestamp <= lastTimestamp) {
            timestamp = System.currentTimeMillis();
        }
        return timestamp;
    }
}
